/*
 * @Author: songxiang songxiang0806@qq.com
 * @Date: 2025-08-28 18:02:34
 * @LastEditors: songxiang songxiang0806@qq.com
 * @LastEditTime: 2025-09-03 16:36:41
 * @FilePath: \supermap-webgl\src\components\model-edit\use-model-edit.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

import { onBeforeUnmount, onMounted, ref } from 'vue'
import { supermapReady } from '/@packages/components'
import { ElLoading, ElMessage } from 'element-plus'
import { selectCursor, defaultCursor } from '/@src/utils'
import { common } from '/@src/api'

export default function () {
  const datasourceName = 'CBD更新1115', //待编辑的数据源名称
    editLayerName = 'BuildingPart' //待编辑的图层名
  const dataUrl = 'http://172.16.15.64:8090/iserver/services/data-SDC/rest/data' //数据服务地址
  const sceneUrl =
    'http://172.16.15.64:8090/iserver/services/3D-SDC/rest/realspace' //场景服务地址
  let s3mtileUpdator = null //定义模型编辑器
  let editLayer = null //定义编辑的模型图层
  // 添加模型事件
  let handlerAdd = null
  // 全局变量,存储添加、更新、删除的对象
  const edits = {
    addFeatures: [],
    updateFeatures: [],
    deleteFeatures: []
  }
  // 组件挂载事件
  onMounted(async () => {
    editLayer = $myapp.viewer.scene.layers.find(editLayerName)
    if (!editLayer) {
      ElMessage.error('编辑图层不存在')
      return
    }
    // 初始化S3M瓦片编辑器
    const datalist = []
    const infoList = await editLayer.datasetInfo()
    for (const item of infoList) {
      //考虑瓦片图层对应多数据集
      const featureDataset = new SuperMap3D.FeatureDataset({
        url: dataUrl,
        dataSource: datasourceName,
        dataSet: item.datasetName
      })
      datalist.push(featureDataset)
    }
    // 初始化模型编辑器
    s3mtileUpdator = new SuperMap3D.S3MTilesEditor({
      layer: editLayer,
      dataset: datalist
    })
    // 开始编辑模型
    s3mtileUpdator.activate()
    // 监听模型编辑器选中模型事件
    s3mtileUpdator.pickEvent.addEventListener(function (feature) {
      if (feature) {
        selectEditFlag.value = true
        currentEditFeature = feature
      } else {
        selectEditFlag.value = false
      }
    })
    // 监听模型编辑器编辑事件，只有触发了才添加到更新组中
    s3mtileUpdator.editEvent.addEventListener((editfeature) => {
      const haseGeometry = SuperMap3D.defined(editfeature.geometry)
      // 判断模型是否已经编辑，如果没编辑，那么就将对象新增到待更新的对象中
      if (editfeature.featureID && haseGeometry) {
        checkInclude(edits.updateFeatures, editfeature)
      }
      currentEditFeature = editfeature
    })

    handlerAdd = new SuperMap3D.ScreenSpaceEventHandler(
      $myapp.viewer.scene.canvas
    )
  })
  // 组件在取消挂载前事件
  onBeforeUnmount(() => {
    onResetAll()
    s3mtileUpdator.destroy()
  })
  const { $myapp } = supermapReady()
  // 是否有选中对象标识
  const selectEditFlag = ref(false)
  // 是否有选中对象
  let currentEditFeature = null
  // 场景中需要隐藏的对象，当点击删除按钮时，可添加并暂时将对象隐藏
  const shouldHideFeatureList = []
  // 待更新的模型数据
  const models = ref([
    {
      url: './datas/jianzu6.s3mb',
      img: './datas/img.png'
    },
    {
      url: './datas/jianzu6.s3mb',
      img: './datas/img.png'
    }
  ])
  // 选中待更新的模型索引
  const selectedModelIndex = ref(0)

  // 删除模型，暂时将模型添加到删除组数中，待统一更新
  const onDeleteGeometry = () => {
    if (!edits.deleteFeatures.includes(currentEditFeature.featureID)) {
      edits.deleteFeatures.push(currentEditFeature.featureID)
      shouldHideFeatureList.push(currentEditFeature.featureID)
    }
    currentEditFeature.geometry = null
    hideDeleteGeometry()
    selectEditFlag.value = false
  }
  // 暂时隐藏图层
  const hideDeleteGeometry = () => {
    editLayer.setObjsVisible(shouldHideFeatureList, false)
  }
  // 选中新模型后替换选中模型
  const onReplaceGeometry = () => {
    const position = currentEditFeature.geometry.geoPosition
    const geoModel = new SuperMap3D.GeoModel3D()

    geoModel.geoFilePath = models.value[selectedModelIndex.value].url

    // 原先模型的高度z为0，这里拔高一下
    // position.z += 21
    geoModel.geoRotationZ = -102
    geoModel.geoScaleX = 1.7
    geoModel.geoScaleY = 1.7
    geoModel.geoScaleZ = 1.7

    geoModel.geoPosition = position
    geoModel.isLatLon = true
    currentEditFeature.geometry = geoModel

    checkInclude(edits.updateFeatures, currentEditFeature)
  }
  // 检查更新对象是否在待更新的数据中，如果不存在则添加
  const checkInclude = (array, feature) => {
    const target = array.find((item) => item.featureID == feature.featureID)
    if (!target) {
      array.push(feature)
    }
  }
  // 将选中模型添加到场景中事件
  const onAddGeometry = () => {
    selectCursor($myapp.viewer)
    handlerAdd.setInputAction(
      function (e) {
        const positionC3 = $myapp.viewer.scene.pickPosition(e.position)

        const lonlat = SuperMap3D.Cartographic.fromCartesian(positionC3)
        const geoModel = new SuperMap3D.GeoModel3D()
        geoModel.geoFilePath = models.value[selectedModelIndex.value].url
        geoModel.geoPosition = new SuperMap3D.Point3D(
          SuperMap3D.Math.toDegrees(lonlat.longitude),
          SuperMap3D.Math.toDegrees(lonlat.latitude),
          lonlat.height
        )
        geoModel.isLatLon = true

        // 设置创建的geoModel绕Z旋转-90度
        // geoModel.geoRotationZ = -90;

        geoModel.geoRotationZ = -103
        // geoModel.geoRotationZ = -77;

        geoModel.geoScaleX = 2
        geoModel.geoScaleY = 2
        geoModel.geoScaleZ = 2

        const feature = s3mtileUpdator.createFeature({
          geometry: geoModel
        })
        currentEditFeature = feature
        edits.addFeatures.push(feature)

        defaultCursor($myapp.viewer)
        handlerAdd.removeInputAction(
          SuperMap3D.ScreenSpaceEventType.LEFT_CLICK,
          SuperMap3D.KeyboardEventModifier.CTRL
        )
      },
      SuperMap3D.ScreenSpaceEventType.LEFT_CLICK,
      SuperMap3D.KeyboardEventModifier.CTRL
    ) //并且与模型选中编辑冲突
  }
  // 点击更新数据集
  const onUpdateDataset = async () => {
    const loading = ElLoading.service({
      lock: true,
      text: '开始更新数据集',
      background: 'rgba(0, 0, 0, 0.7)'
    })
    if (
      edits.addFeatures.length == 0 &&
      edits.updateFeatures.length == 0 &&
      edits.deleteFeatures.length == 0
    ) {
      loading.close()
      ElMessage.info('没有需要更新的模型')
      return
    }
    //目前已支持同时传多个
    const result = await s3mtileUpdator.applyEdit(edits)
    loading.close()
    if (result) {
      console.log('result===', result)
      ElMessage.success('更新数据集成功，请点击更新瓦片')
      if (result.updateFeatureResult.succeed) {
        console.log('update', result.updateFeatureResult)
      }
      if (result.deleteFeatureResult.succeed) {
        console.log('delete', result.deleteFeatureResult)
      }
      if (result.addFeatureResult.succeed) {
        console.log('add', result.addFeatureResult)
      }
      edits.addFeatures = []
      edits.updateFeatures = []
      edits.deleteFeatures = []
    } else {
      console.log(result)
      ElMessage.error('更新数据集失败')
    }
  }
  // 点击更新瓦片
  const onUpdateS3MB = async () => {
    const loading = ElLoading.service({
      lock: true,
      text: '开始更新瓦片',
      background: 'rgba(0, 0, 0, 0.7)'
    })
    if (
      edits.addFeatures.length > 0 ||
      edits.updateFeatures.length > 0 ||
      edits.deleteFeatures.length > 0
    ) {
      loading.close()
      ElMessage.info('请先更新数据集后，再点击更新瓦片')
      return
    }
    // 数据集区域范围：在该区域内的模型编辑才有效
    const datasetRect = [
      {
        leftBottom: {
          x: SuperMap3D.Math.toDegrees(editLayer.layerBounds.west),
          y: SuperMap3D.Math.toDegrees(editLayer.layerBounds.south)
        },
        rightTop: {
          x: SuperMap3D.Math.toDegrees(editLayer.layerBounds.east),
          y: SuperMap3D.Math.toDegrees(editLayer.layerBounds.north)
        }
      }
    ]
    const data = {
      boundsList: datasetRect
    }
    const updateurl =
      sceneUrl + '/datas/' + editLayer.name + '/updatecache.json'
    const res: any = await common.post(updateurl, JSON.stringify(data))
    console.log('res===', res)
    if (res && res.customResult) {
      ElMessage.success('更新瓦片成功')
    } else {
      ElMessage.error('更新瓦片失败')
      console.log(res)
    }
    loading.close()
  }
  // 点击重置所有
  const onResetAll = () => {
    s3mtileUpdator.resetAll()
    edits.addFeatures = []
    edits.updateFeatures = []
    edits.deleteFeatures = []
  }
  return {
    models,
    selectedModelIndex,
    selectEditFlag,
    onDeleteGeometry,
    onReplaceGeometry,
    onAddGeometry,
    onUpdateDataset,
    onUpdateS3MB,
    onResetAll
  }
}
